#include <stdlib.h>
#include <string.h>

#include <debug.h>
#include <os_api.h>
#include <hal/gpio.h>

#define TASK_STACK_SIZE (10 * 1024)
static char _task_stack[TASK_STACK_SIZE];

static OS_HISR _app_gpio_HISR = NULL;
static UINT32 _app_gpio_val = -1;

static void app_gpio_hisr(void)
{
    UINT32 val;

    val = hal_GpioIn(GPIO_PIN_26);
    if (_app_gpio_val != val)
    {
        _app_gpio_val = val;
        LOG_PRINTF("%s val %d", __func__, val);
    }
}

static void app_gpio_isr(void)
{
    OS_Activate_HISR(&_app_gpio_HISR);
}

static void app_gpio_isr_init()
{
    int ret;
    GPIOConfiguration gpio_config;

    OS_Create_HISR(&_app_gpio_HISR, "gpiohisr", app_gpio_hisr, HISR_PRIORITY_1);

    memset(&gpio_config, 0, sizeof(gpio_config));
    gpio_config.pinDir = GPIO_IN_PIN;
    gpio_config.pinEd = GPIO_TWO_EDGE;
    gpio_config.pinPull = GPIO_PULLUP_ENABLE;
    gpio_config.isr = app_gpio_isr;
    gpio_config.wu = NULL;
    ret = hal_ConfigGpio(GPIO_PIN_26, gpio_config);
    ASSERT(ret == GPIORC_OK);
}

static void app_task(void *param)
{
    unsigned count = 0;
    int val = 0;

    hal_GpioSetDir(GPIO_PIN_25, GPIO_OUT_PIN);
    hal_GpioOut(GPIO_PIN_25, val);

    app_gpio_isr_init();

    while (1)
    {
        sleep(3);
        count++;

        val = val ? 0 : 1;
        hal_GpioOut(GPIO_PIN_25, val);

        LOG_PRINTF("%s test count %u GPIO val %d", __func__, count, val);
    }
}

int main()
{
    int ret;
    OSTaskRef task_ref; // because following task will never exit, so we do not use task handle, so we don't care it's handle

    ret = OSATaskCreate(&task_ref, _task_stack, TASK_STACK_SIZE, OS_APP_PRIORITY, "app", app_task, NULL);
    ASSERT(ret == OS_SUCCESS);
}
